package com.choosefine.paycenter.common.utils;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;

import java.io.StringWriter;

/**
 * Comments：
 * Author：Jay Chang
 * Create Date：2017/4/15
 * Modified By：
 * Modified Date：
 * Why & What is modified：
 * Version：v1.0
 */
public class XmlUtils {
    private static XmlUtils xmlUtils;
    private static final String XML_HEADER_GB18030 = "<?xml version=\"1.0\" encoding=\"GB18030\"?>";
    private static final String XML_HEADER_GB2312 = "<?xml version=\"1.0\" encoding=\"GB2312\"?>";
    private static final String XML_HEADER_UTF8 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
    private static final String XML_HEADER_DEFAULT = XML_HEADER_GB2312;
    private static XStream xStream;

    private static enum XmlHeader{
        GB2312(XML_HEADER_GB2312),GB18030(XML_HEADER_GB18030), UTF8(XML_HEADER_UTF8);
        private String desc;
        private XmlHeader(String desc){
            this.desc =desc;
        }
        public String getDesc(){
            return this.desc;
        }
    }

    static {
        xStream = new XStream(new Xpp3Driver());
    }

    private XmlUtils(){
    }

    public static synchronized XmlUtils getInstance(){
        return null != xmlUtils ? xmlUtils : (xmlUtils = new XmlUtils());
    }

    public String toXml(Object obj){
        return toXml(obj,"GB2312");
    }

    /**
     * java对象生成XML
     * @param obj
     * @param encoding(可选值：1.GB2112,2.GB18030,3.UTF8)
     * @return
     */
    public String toXml(Object obj,String encoding){
        xStream.autodetectAnnotations(true);
        xStream.processAnnotations(obj.getClass());
        StringWriter stringWriter = new StringWriter();
        CompactWriter compactWriter = new CompactWriter(stringWriter,new XmlFriendlyNameCoder("_-","_"));
        xStream.marshal(obj,compactWriter);
        return XmlHeader.valueOf(encoding).getDesc()+stringWriter.toString();
    }

    /**
     *  XML转java对象
     * @param xml
     * @param clazz
     * @return
     */
    public  <T> T fromXml(String xml,Class<T> clazz){
        xStream.autodetectAnnotations(true);
        xStream.processAnnotations(clazz);
        Object obj = null;
        try {
            obj = clazz.newInstance();
        } catch (Exception e){
            throw new RuntimeException(e);
        }
        xStream.fromXML(xml,obj);
        return (T)obj;
    }

}
